import asyncio
import json
import os
import random
import sys
import time
from datetime import datetime

import cv2
import numpy as np
from fastapi import APIRouter, Query, Body, HTTPException
from sse_starlette.sse import EventSourceResponse

# 添加multiprocessing导入
from multiprocessing import Process, Event

# 修改海康SDK路径
current_dir = os.path.dirname(os.path.abspath(__file__))
sdk_path = os.path.join(current_dir, "hik", "MvImport")
sys.path.append(sdk_path)

from MvCameraControl_class import *

from app.controllers.rotor import rotor_type_controller
from app.controllers.detection import detection_controller
from app.controllers.storage import storage_config_controller
from app.controllers.camera import camera_config_controller
from app.core.ctx import CTX_USER_ID
from app.core.dependency import DependAuth
from app.schemas.base import Success, SuccessExtra
from app.schemas.detection import DetectionCreate, DetectionUpdate
from app.api.v1.detection.plc.siemens_reader import SiemensReader

router = APIRouter()

# 全局变量用于控制相机线程
g_bExit = False
g_camera = None
g_video_writer = None
MAX_DURATION = 600  # 10分钟 (60秒 * 10)

# 添加新的全局变量
g_high_speed_camera1 = None
g_high_speed_camera2 = None
g_high_speed_exit = False

# 添加全局变量用于存储预期转速
g_expected_speed = None

# 添加全局变量
g_frame_lists = {
    "camera1": [],  # 每个元素是 {'frame': frame, 'timestamp': timestamp}
    "camera2": []
}
FRAMES_PER_BATCH = 100  # 每100帧处理一次

# 添加时间戳误差常量
TIMESTAMP_TOLERANCE = 2000  # 2毫秒 = 2000微秒

# 添加全局变量用于存储时间戳基准点
g_timestamp_base = {
    "camera1": None,
    "camera2": None
}

# 相机图像捕获线程
def camera_capture_process(stop_event, image_path, video_path, camera_config):
    """独立进程处理慢速相机图像采集和初始化"""
    print("Starting camera capture process")
    print(f"Image path: {image_path}")
    print(f"Video path: {video_path}")
    
    try:
        start_time = time.time()
        print("Starting slow camera initialization...")
        
        # 初始化慢速相机
        camera = MvCamera()
        deviceList = MV_CC_DEVICE_INFO_LIST()
        ret = MvCamera.MV_CC_EnumDevices(MV_GIGE_DEVICE, deviceList)
        print(f"Device enumeration completed, time elapsed: {time.time() - start_time:.3f}s")

        # 查找MV-CS050-10GM-PRO相机
        device_index = -1
        for i in range(deviceList.nDeviceNum):
            mvcc_dev_info = cast(deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents
            if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE:
                model_name = ""
                for per in mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName:
                    if per == 0:
                        break
                    model_name += chr(per)
                if "MV-CS050-10GM-PRO" in model_name:
                    device_index = i
                    break

        if device_index == -1:
            raise Exception("MV-CS050-10GM-PRO camera not found")

        # 创建相机实例并打开设备
        stDeviceList = cast(deviceList.pDeviceInfo[device_index], POINTER(MV_CC_DEVICE_INFO)).contents
        ret = camera.MV_CC_CreateHandle(stDeviceList)
        if ret != 0:
            raise Exception("Failed to create camera handle")
            
        ret = camera.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
        if ret != 0:
            raise Exception("Failed to open camera")
            
        # 直接使用传入的配置
        camera.MV_CC_SetFloatValue("AcquisitionFrameRate", float(camera_config.frame_rate))
        camera.MV_CC_SetFloatValue("ExposureTime", float(camera_config.exposure_time))
        camera.MV_CC_SetFloatValue("Gain", float(camera_config.gain))
        camera.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
        
        # 获取实际参数值
        stParam = MVCC_FLOATVALUE()
        camera.MV_CC_GetFloatValue("ResultingFrameRate", stParam)
        
        stParamWidth = MVCC_INTVALUE()
        camera.MV_CC_GetIntValue("Width", stParamWidth)
        
        stParamHeight = MVCC_INTVALUE()
        camera.MV_CC_GetIntValue("Height", stParamHeight)
        
        # 开始取流
        ret = camera.MV_CC_StartGrabbing()
        if ret != 0:
            raise Exception("Failed to start grabbing")
            
        # 创建视频写入器
        video_file = os.path.join(video_path, f"{int(time.time())}.mp4").replace('\\', '/')
        fourcc = cv2.VideoWriter_fourcc(*'H264')
        video_writer = cv2.VideoWriter(
            video_file,
            fourcc,
            stParam.fCurValue,
            (stParamWidth.nCurValue, stParamHeight.nCurValue),
            True
        )
        
        if not video_writer.isOpened():
            raise Exception("Failed to create video writer")
            
        # 开始图像采集循环
        frame_count = 0
        last_save_time = 0
        
        stOutFrame = MV_FRAME_OUT()
        memset(byref(stOutFrame), 0, sizeof(stOutFrame))
        
        while not stop_event.is_set():
            current_time = time.time()
            elapsed_time = current_time - start_time
            
            if elapsed_time >= MAX_DURATION:
                print(f"Recording reached maximum duration of {MAX_DURATION} seconds")
                break
                
            ret = camera.MV_CC_GetImageBuffer(stOutFrame, 1000)
            
            if ret != 0:
                print(f"Failed to get image buffer, ret: {ret}")
                if ret == 2147483651:
                    try:
                        print("Trying to restart grabbing...")
                        camera.MV_CC_StopGrabbing()
                        camera.MV_CC_StartGrabbing()
                    except Exception as e:
                        print(f"Failed to restart grabbing: {str(e)}")
                time.sleep(0.001)
                continue
                
            if stOutFrame.pBufAddr:
                try:
                    if stOutFrame.stFrameInfo.nFrameLen <= 0:
                        print("Invalid frame data: frame length is 0")
                        continue
                    
                    data_buf = (c_ubyte * stOutFrame.stFrameInfo.nFrameLen)()
                    cdll.msvcrt.memcpy(byref(data_buf), stOutFrame.pBufAddr, stOutFrame.stFrameInfo.nFrameLen)
                    
                    frame = np.frombuffer(data_buf, dtype=np.uint8)
                    frame = frame.reshape((stOutFrame.stFrameInfo.nHeight, stOutFrame.stFrameInfo.nWidth, -1))
                    
                    if frame.shape[2] == 1:
                        frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)
                    elif frame.shape[2] == 4:
                        frame = cv2.cvtColor(frame, cv2.COLOR_RGBA2BGR)
                    
                    # 写入视频
                    if video_writer:
                        frame = cv2.resize(frame, (stParamWidth.nCurValue, stParamHeight.nCurValue))
                        try:
                            video_writer.write(frame)
                            frame_count += 1
                            if frame_count % int(stParam.fCurValue) == 0:
                                print(f"Written frame {frame_count} to video, elapsed time: {elapsed_time:.1f}s")
                        except Exception as e:
                            print(f"Failed to write video frame: {str(e)}")
                    
                    # 每秒保存一张图片
                    if current_time - last_save_time >= 1.0:
                        image_file = os.path.join(image_path, f"{int(current_time)}.jpg")
                        try:
                            cv2.imwrite(image_file, frame)
                            last_save_time = current_time
                        except Exception as e:
                            print(f"Failed to save image {image_file}: {str(e)}")
                    
                except Exception as e:
                    print(f"Error processing frame: {str(e)}")
                finally:
                    camera.MV_CC_FreeImageBuffer(stOutFrame)
                    
            time.sleep(0.001)  # 小延迟避免CPU占用过高
        
        # 记录最终状态
        print(f"Recording finished. Total frames: {frame_count}, duration: {time.time() - start_time:.1f}s")
        
        # 如果是因为时间限制退出,需要正确关闭资源
        if time.time() - start_time >= MAX_DURATION:
            if video_writer:
                try:
                    video_writer.release()
                except Exception as e:
                    print(f"Error releasing video writer: {str(e)}")
                    
            if camera:
                try:
                    camera.MV_CC_StopGrabbing()
                    camera.MV_CC_CloseDevice()
                    camera.MV_CC_DestroyHandle()
                except Exception as e:
                    print(f"Error releasing camera resources: {str(e)}")
        else:
            # 正常停止时的资源释放
            if video_writer:
                video_writer.release()
            if camera:
                camera.MV_CC_StopGrabbing()
                camera.MV_CC_CloseDevice()
                camera.MV_CC_DestroyHandle()
                
    except Exception as e:
        print(f"Error in camera capture process: {str(e)}")
    finally:
        # 清理资源
        if 'video_writer' in locals():
            video_writer.release()
        if 'camera' in locals():
            try:
                camera.MV_CC_StopGrabbing()
                camera.MV_CC_CloseDevice()
                camera.MV_CC_DestroyHandle()
            except Exception as e:
                print(f"Error cleaning up camera: {str(e)}")
                
        print("Camera capture process finished")

@router.get("/list", summary="获取检测记录列表", dependencies=[DependAuth])
async def get_detection_list(
        page: int = Query(1, description="页码"),
        page_size: int = Query(10, description="每页数量"),
        detection_type: int = Query(None, description="检测类型"),
        operator_id: int = Query(None, description="操作员ID"),
        start_time: str = Query(None, description="开始时间"),
        end_time: str = Query(None, description="结束时间"),
):
    """获取检测记录列表"""
    data = await detection_controller.get_detection_list(
        page=page,
        page_size=page_size,
        detection_type=detection_type,
        operator_id=operator_id,
        start_time=start_time,
        end_time=end_time
    )
    return SuccessExtra(data=data.get("items"), total=data.get("total"))


@router.get("/get", summary="获取检测记录详情")
async def get_detection(
        detection_id: int = Query(..., description="检测记录ID"),
):
    """获取检测记录详情"""
    detection = await detection_controller.get(id=detection_id)
    return Success(data=await detection.to_dict())


@router.post("/control", summary="无人机控制")
async def control_uav(
        rotor_type_id: int = Body(..., description="旋翼类型ID"),
        detection_type: int = Body(..., description="检测类型"),
):
    return Success(msg="Control command sent successfully")


@router.post("/start", summary="开始检测", dependencies=[DependAuth])
async def start_detection(detection_in: DetectionCreate):
    global g_bExit, g_high_speed_exit, g_expected_speed
    global g_camera, g_video_writer, g_high_speed_camera1, g_high_speed_camera2
    global g_frame_lists, g_plc_reader
    
    start_time = time.time()
    print("Starting detection process...")
    
    try:
        # 确保所有全局变量都被重置
        g_bExit = False
        g_high_speed_exit = False
        g_camera = None
        g_video_writer = None
        g_high_speed_camera1 = None
        g_high_speed_camera2 = None
        
        # 重置帧列表
        g_frame_lists = {
            "camera1": [],
            "camera2": []
        }
        
        # 获取存储配置
        storage_config = await storage_config_controller.get_config()
        if not storage_config:
            raise HTTPException(status_code=400, detail="Storage configuration not found")
            
        # 创建检测记录
        detection = await detection_controller.create(
            obj_in=detection_in,
            operator_id=CTX_USER_ID.get()
        )
        print(f"Detection record created, time elapsed: {time.time() - start_time:.3f}s")

        # 创建存储目录
        detection_folder = str(detection.id)
        image_path = os.path.join(storage_config.image_path, detection_folder, "img").replace('\\', '/')
        video_path = os.path.join(storage_config.video_path, detection_folder).replace('\\', '/')
        
        os.makedirs(image_path, exist_ok=True)
        os.makedirs(video_path, exist_ok=True)
        print(f"Storage directories created, time elapsed: {time.time() - start_time:.3f}s")
        
        # 更新检测记录的路径
        await detection_controller.update(
            id=detection.id,
            obj_in=DetectionUpdate(
                id=detection.id,
                image_path=image_path,
                video_path=video_path
            )
        )
        print(f"Detection record paths updated, time elapsed: {time.time() - start_time:.3f}s")
        
        # 初始化慢速相机
        await init_slow_camera(image_path, video_path)
        print(f"Slow camera initialization completed, time elapsed: {time.time() - start_time:.3f}s")
        
        # 初始化高速相机
        await init_high_speed_cameras()
        print(f"High speed cameras initialization completed, time elapsed: {time.time() - start_time:.3f}s")
        
        # 获取预期转速
        rotor_type = await rotor_type_controller.get(id=detection_in.rotor_type_id)
        g_expected_speed = rotor_type.preset_speed
        
        # 尝试初始化PLC读取器，但不影响主流程
        try:
            g_plc_reader = SiemensReader()
            if g_plc_reader.connect():
                print(f"PLC reader initialized, time elapsed: {time.time() - start_time:.3f}s")
            else:
                print("PLC connection failed, will use default attitude angle (0)")
        except Exception as e:
            print(f"Error initializing PLC reader: {str(e)}")
            g_plc_reader = None
        
        # 启动高速相机采集线程
        high_speed_config = await camera_config_controller.get_by_camera_type("MV-CS004-10UC")
        asyncio.create_task(high_speed_camera_thread(g_high_speed_camera1, "camera1", high_speed_config.frame_rate))
        asyncio.create_task(high_speed_camera_thread(g_high_speed_camera2, "camera2", high_speed_config.frame_rate))
        
        print(f"Detection start completed, total time: {time.time() - start_time:.3f}s")
        return Success(data={"detection_id": detection.id})
        
    except Exception as e:
        print(f"Error in start_detection: {str(e)}")
        # 清理资源
        if g_video_writer:
            try:
                g_video_writer.release()
                print("Video writer released")
            except Exception as e:
                print(f"Error releasing video writer: {str(e)}")
            finally:
                g_video_writer = None
                
        if g_camera:
            try:
                g_camera.MV_CC_StopGrabbing()
                g_camera.MV_CC_CloseDevice()
                g_camera.MV_CC_DestroyHandle()
                print("Camera resources released")
            except Exception as e:
                print(f"Error releasing camera resources: {str(e)}")
            finally:
                g_camera = None
                
        if g_high_speed_camera1:
            try:
                g_high_speed_camera1.MV_CC_StopGrabbing()
                g_high_speed_camera1.MV_CC_CloseDevice()
                g_high_speed_camera1.MV_CC_DestroyHandle()
                print("High-speed camera 1 resources released")
            except Exception as e:
                print(f"Error releasing high-speed camera 1 resources: {str(e)}")
            finally:
                g_high_speed_camera1 = None
                
        if g_high_speed_camera2:
            try:
                g_high_speed_camera2.MV_CC_StopGrabbing()
                g_high_speed_camera2.MV_CC_CloseDevice()
                g_high_speed_camera2.MV_CC_DestroyHandle()
                print("High-speed camera 2 resources released")
            except Exception as e:
                print(f"Error releasing high-speed camera 2 resources: {str(e)}")
            finally:
                g_high_speed_camera2 = None
                
        raise HTTPException(status_code=500, detail=str(e))


# 修改高速相机图像采集线程
async def high_speed_camera_thread(camera, camera_name, frame_rate):
    global g_high_speed_exit, g_frame_lists
    
    stOutFrame = MV_FRAME_OUT()
    memset(byref(stOutFrame), 0, sizeof(stOutFrame))
    
    frame_count = 0
    start_time = time.perf_counter_ns()
    last_fps_time = start_time
    
    while not g_high_speed_exit:
        total_start = time.perf_counter_ns()
        loop_start = time.perf_counter_ns()
        
        try:
            # 1. 获取图像
            get_image_start = time.perf_counter_ns()
            ret = camera.MV_CC_GetImageBuffer(stOutFrame, 1000)
            get_image_time = (time.perf_counter_ns() - get_image_start) / 1000
            
            if ret == 0 and stOutFrame.pBufAddr is not None:
                try:
                    # 2. 转换图像格式
                    convert_start = time.perf_counter_ns()
                    data_buf = (c_ubyte * stOutFrame.stFrameInfo.nFrameLen)()
                    cdll.msvcrt.memcpy(byref(data_buf), stOutFrame.pBufAddr, stOutFrame.stFrameInfo.nFrameLen)
                    frame = np.frombuffer(data_buf, dtype=np.uint8)
                    frame = frame.reshape((stOutFrame.stFrameInfo.nHeight, stOutFrame.stFrameInfo.nWidth, -1))
                    convert_time = (time.perf_counter_ns() - convert_start) / 1000
                    
                    # 3. 添加到帧列表
                    append_start = time.perf_counter_ns()
                    g_frame_lists[camera_name].append({
                        'frame': frame,
                        'timestamp': stOutFrame.stFrameInfo.nHostTimeStamp
                    })
                    append_time = (time.perf_counter_ns() - append_start) / 1000
                    
                    # 4. 释放缓冲区
                    free_start = time.perf_counter_ns()
                    camera.MV_CC_FreeImageBuffer(stOutFrame)
                    free_time = (time.perf_counter_ns() - free_start) / 1000
                    
                    frame_count += 1
                    current_time = time.perf_counter_ns()
                    
                    # 性能监控代码
                    operations_time = (time.perf_counter_ns() - loop_start) / 1000
                    
                    await asyncio.sleep(0)
                    
                    total_time = (time.perf_counter_ns() - total_start) / 1000
                    
                    # if (current_time - last_fps_time) >= 1_000_000_000:
                    #     fps = frame_count / ((current_time - start_time) / 1_000_000_000)
                    #     buffer_size = len(g_frame_lists[camera_name])
                    #     print(f"{camera_name} Performance:")
                    #     print(f"  - Get Image: {get_image_time:.3f}µs")
                    #     print(f"  - Convert: {convert_time:.3f}µs")
                    #     print(f"  - Append: {append_time:.3f}µs")
                    #     print(f"  - Free Buffer: {free_time:.3f}µs")
                    #     print(f"  - Operations time: {operations_time:.3f}µs")
                    #     print(f"  - Total with sleep: {total_time:.3f}µs")
                    #     print(f"  - FPS: {fps:.2f}, Buffer size: {buffer_size}")
                    #     print(f"  - Average time per frame: {1_000_000/fps:.3f}µs")
                    #     last_fps_time = current_time
                        
                finally:
                    camera.MV_CC_FreeImageBuffer(stOutFrame)
                    
        except Exception as e:
            print(f"Error in {camera_name} processing: {str(e)}")
            # 出现异常时也要尝试释放资源
            try:
                camera.MV_CC_FreeImageBuffer(stOutFrame)
            except:
                pass
        
        # 删除这里的sleep，只保留上面那个

# 修改图像处理函数，注释掉时间戳打印
async def process_high_speed_frames(frames1_with_time, frames2_with_time):
    """处理高速相机图像并返回检测结果"""
    global g_expected_speed, g_plc_reader

    # 获取姿态角
    attitude_angle = 0  # 默认姿态角为0
    try:
        if g_plc_reader and g_plc_reader.connected:
            plc_angle = g_plc_reader.read_lreal(db_number=1, start_offset=0)
            if plc_angle is not None:
                attitude_angle = round(plc_angle, 2)
    except Exception as e:
        print(f"Error reading PLC data: {str(e)}")
        # PLC读取错误时使用默认值0
        attitude_angle = 0

    # 生成转子数据
    rotors = []
    for i in range(4):
        actual_speed = random.randint(int(g_expected_speed * 0.9), int(g_expected_speed * 1.1))
        fluctuation = (actual_speed - g_expected_speed) * 100 / g_expected_speed
        rotors.append({
            "direction": random.choice(["顺时针", "逆时针"]),
            "speed": actual_speed,
            "fluctuation": round(fluctuation, 2),
            "attitude_angle": attitude_angle  # 使用从PLC读取的姿态角或默认值
        })

    detection_states = [
        "平稳飞行", "异常飞行", "俯仰机动", "偏航机动",
        "横滚机动", "机动异常", "未知机动"
    ]

    return {
        "rotors": rotors,
        "detection_result": random.choice(detection_states),
        "result_code": random.randint(1, 7)
    }

# 修改detection_data_generator，添加处理频率监控
async def detection_data_generator():
    """实时检测数据生成器"""
    global g_frame_lists, g_high_speed_exit
    
    process_count = 0
    start_time = time.time()
    last_print_time = start_time
    
    while True:
        if (len(g_frame_lists["camera1"]) >= FRAMES_PER_BATCH and 
            len(g_frame_lists["camera2"]) >= FRAMES_PER_BATCH):
            
            current_time = time.time()
            process_count += 1
            
            # 打印处理频率
            if current_time - last_print_time >= 1.0:
                process_rate = process_count / (current_time - start_time)
                # print(f"Processing rate: {process_rate:.2f} batches/second")
                last_print_time = current_time
            
            frames1_with_time = g_frame_lists["camera1"][-FRAMES_PER_BATCH:]
            frames2_with_time = g_frame_lists["camera2"][-FRAMES_PER_BATCH:]
            
            result = await process_high_speed_frames(frames1_with_time, frames2_with_time)
            
            # 只保留最新的一帧，避免处理延迟
            g_frame_lists["camera1"] = g_frame_lists["camera1"][-1:]
            g_frame_lists["camera2"] = g_frame_lists["camera2"][-1:]
            
            yield {
                "event": "message",
                "data": json.dumps(result)
            }
        
        await asyncio.sleep(0.001)  # 1ms的延迟


@router.get("/stream", summary="检测数据流")
async def detection_stream():
    return EventSourceResponse(detection_data_generator())


@router.post("/stop", summary="停止检测")
async def stop_detection(
        data: dict = Body(..., description="检测记录ID"),
):
    global g_bExit, g_camera, g_video_writer
    global g_high_speed_exit, g_high_speed_camera1, g_high_speed_camera2
    global g_capture_stop_event, g_capture_process
    global g_frame_lists, g_expected_speed, g_plc_reader
    
    try:
        detection_id = data.get('detection_id')
        if not isinstance(detection_id, int):
            try:
                detection_id = int(detection_id)
            except (TypeError, ValueError):
                raise HTTPException(status_code=400, detail="Invalid detection_id")

        print("Stopping detection and releasing resources...")
        
        # 停止所有相机采集
        g_bExit = True
        g_high_speed_exit = True
        
        # 等待一小段时间确保所有帧都被处理
        await asyncio.sleep(1)
        
        # 停止慢速相机采集进程
        if g_capture_stop_event:
            g_capture_stop_event.set()
        if g_capture_process:
            g_capture_process.join(timeout=5)
            if g_capture_process.is_alive():
                g_capture_process.terminate()
        
        # 释放高速相机资源
        if g_high_speed_camera1:
            try:
                g_high_speed_camera1.MV_CC_StopGrabbing()
                g_high_speed_camera1.MV_CC_CloseDevice()
                g_high_speed_camera1.MV_CC_DestroyHandle()
                print("High-speed camera 1 resources released")
            except Exception as e:
                print(f"Error releasing high-speed camera 1 resources: {str(e)}")
            finally:
                g_high_speed_camera1 = None
                
        if g_high_speed_camera2:
            try:
                g_high_speed_camera2.MV_CC_StopGrabbing()
                g_high_speed_camera2.MV_CC_CloseDevice()
                g_high_speed_camera2.MV_CC_DestroyHandle()
                print("High-speed camera 2 resources released")
            except Exception as e:
                print(f"Error releasing high-speed camera 2 resources: {str(e)}")
            finally:
                g_high_speed_camera2 = None
        
        # 尝试断开PLC连接
        if g_plc_reader:
            try:
                g_plc_reader.disconnect()
                print("PLC connection closed")
            except Exception as e:
                print(f"Error disconnecting PLC: {str(e)}")
            finally:
                g_plc_reader = None
        
        # 重置所有全局变量
        g_bExit = False
        g_high_speed_exit = False
        g_camera = None
        g_video_writer = None
        g_capture_stop_event = None
        g_capture_process = None
        g_expected_speed = None
        
        # 清空帧列表
        g_frame_lists = {
            "camera1": [],
            "camera2": []
        }
        
        # 更新检测记录
        detection = await detection_controller.get(id=detection_id)
        if not detection:
            raise HTTPException(status_code=404, detail="Detection record not found")

        # 计算持续时间
        start_time = detection.detection_time.replace(tzinfo=None)
        current_time = datetime.now()
        duration = int((current_time - start_time).total_seconds())
        
        await detection_controller.update(
            id=detection_id,
            obj_in=DetectionUpdate(
                id=detection_id,
                status=1,
                duration=duration
            )
        )
        
        return Success(msg="Detection stopped successfully")

    except Exception as e:
        print(f"Error stopping detection: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/images", summary="获取检测记录图片列表", dependencies=[DependAuth])
async def get_detection_images(
        data: dict = Body(..., description="检测记录信息")
):
    """获取检测记录的图片列表"""
    try:
        detection_id = data.get('detection_id')
        if not isinstance(detection_id, int):
            try:
                detection_id = int(detection_id)
            except (TypeError, ValueError):
                raise HTTPException(status_code=400, detail="Invalid detection_id")

        # 获取检记录
        detection = await detection_controller.get(id=detection_id)
        if not detection:
            raise HTTPException(status_code=404, detail="Detection record not found")

        # 获取图片目录
        image_path = detection.image_path
        if not image_path or not os.path.exists(image_path):
            return Success(data=[])

        # 获取目录下的所有图片文件返回完整的本地文件路径
        image_files = []
        for file in os.listdir(image_path):
            if file.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
                # 返回完整的本地文件路径
                file_path = os.path.join(image_path, file).replace('\\', '/')
                image_files.append(file_path)

        return Success(data=image_files)

    except Exception as e:
        print(f"Error getting detection images: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))


# 添加获取视频路径的接口
@router.post("/video", summary="获取检测记录视频路径", dependencies=[DependAuth])
async def get_detection_video(
        data: dict = Body(..., description="检测记录信息")
):
    """获取检测记录的视频路径"""
    try:
        detection_id = data.get('detection_id')
        if not isinstance(detection_id, int):
            try:
                detection_id = int(detection_id)
            except (TypeError, ValueError):
                raise HTTPException(status_code=400, detail="Invalid detection_id")

        # 获取检测记录
        detection = await detection_controller.get(id=detection_id)
        if not detection:
            raise HTTPException(status_code=404, detail="Detection record not found")

        # 获取频录
        video_path = detection.video_path
        if not video_path or not os.path.exists(video_path):
            return Success(data=None)

        # 获取目录下的第一个视频文件
        for file in os.listdir(video_path):
            if file.lower().endswith(('.mp4', '.avi', '.mkv')):
                file_path = os.path.join(video_path, file).replace('\\', '/')
                return Success(data=file_path)

        return Success(data=None)

    except Exception as e:
        print(f"Error getting detection video: {str(e)}")
        raise HTTPException(status_code=500, detail=str(e))

async def init_slow_camera(image_path, video_path):
    """启动独立进程处理慢速相机"""
    try:
        # 先获取相机配置
        camera_config = await camera_config_controller.get_by_camera_type("MV-CS050-10GM-PRO")
        
        # 创建停止事件和进程
        stop_event = Event()
        capture_process = Process(
            target=camera_capture_process,
            args=(stop_event, image_path, video_path, camera_config)  # 传入配置
        )
        capture_process.start()
        
        # 保存stop_event用于后续停止进程
        global g_capture_stop_event, g_capture_process
        g_capture_stop_event = stop_event
        g_capture_process = capture_process
        
        return True

    except Exception as e:
        print(f"Error starting camera process: {str(e)}")
        raise

async def init_high_speed_cameras():
    """初始化高速相机"""
    global g_high_speed_camera1, g_high_speed_camera2
    
    start_time = time.time()
    print("Starting high speed cameras initialization...")
    
    try:
        # 初始化相机实例
        g_high_speed_camera1 = MvCamera()
        g_high_speed_camera2 = MvCamera()
        print(f"Camera instances created, time elapsed: {time.time() - start_time:.3f}s")
        
        # 枚举USB设备
        deviceList = MV_CC_DEVICE_INFO_LIST()
        ret = MvCamera.MV_CC_EnumDevices(MV_USB_DEVICE, deviceList)
        print(f"USB devices enumerated, time elapsed: {time.time() - start_time:.3f}s")

        # 查找高速相机
        high_speed_cameras = []
        for i in range(deviceList.nDeviceNum):
            mvcc_dev_info = cast(deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents
            if mvcc_dev_info.nTLayerType == MV_USB_DEVICE:
                model_name = ""
                for per in mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName:
                    if per == 0:
                        break
                    model_name += chr(per)
                if "MV-CS004-10UC" in model_name:
                    high_speed_cameras.append((i, mvcc_dev_info))

        if len(high_speed_cameras) < 2:
            raise HTTPException(status_code=404, detail="Not enough MV-CS004-10UC cameras found")

        # 初始化两个高速相机
        camera_config = await camera_config_controller.get_by_camera_type("MV-CS004-10UC")
        for idx, (device_index, dev_info) in enumerate(high_speed_cameras[:2]):
            init_start = time.time()
            camera = g_high_speed_camera1 if idx == 0 else g_high_speed_camera2
            
            # 创建相机句柄并打设备
            ret = camera.MV_CC_CreateHandle(dev_info)
            if ret != 0:
                raise HTTPException(status_code=500, detail=f"Failed to create handle for camera {idx+1}")
                
            ret = camera.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
            if ret != 0:
                raise HTTPException(status_code=500, detail=f"Failed to open camera {idx+1}")
            print(f"Camera {idx+1} opened, time elapsed: {time.time() - init_start:.3f}s")

            # 设置相机参数
            param_start = time.time()
            try:
                # 设置帧率
                ret = camera.MV_CC_SetFloatValue("AcquisitionFrameRate", float(camera_config.frame_rate))
                if ret != 0:
                    print(f"Failed to set frame rate for camera {idx+1}, ret: {ret}")
                # 获取实际帧率
                stParam = MVCC_FLOATVALUE()
                ret = camera.MV_CC_GetFloatValue("ResultingFrameRate", stParam)
                if ret == 0:
                    print(f"Actual camera {idx+1} frame rate: {stParam.fCurValue}")
                else:
                    print(f"Failed to get actual frame rate for camera {idx+1}, ret: {ret}")

                # 设置曝光时间
                ret = camera.MV_CC_SetFloatValue("ExposureTime", float(camera_config.exposure_time))
                if ret != 0:
                    print(f"Failed to set exposure time for camera {idx+1}, ret: {ret}")
                # 获取实际曝光时间
                stParamExposure = MVCC_FLOATVALUE()
                ret = camera.MV_CC_GetFloatValue("ExposureTime", stParamExposure)
                if ret == 0:
                    print(f"Actual camera {idx+1} exposure time: {stParamExposure.fCurValue}")
                else:
                    print(f"Failed to get actual exposure time for camera {idx+1}, ret: {ret}")

                # 设置增益
                ret = camera.MV_CC_SetFloatValue("Gain", float(camera_config.gain))
                if ret != 0:
                    print(f"Failed to set gain for camera {idx+1}, ret: {ret}")
                # 获取实际增益
                stParamGain = MVCC_FLOATVALUE()
                ret = camera.MV_CC_GetFloatValue("Gain", stParamGain)
                if ret == 0:
                    print(f"Actual camera {idx+1} gain: {stParamGain.fCurValue}")
                else:
                    print(f"Failed to get actual gain for camera {idx+1}, ret: {ret}")

                # 设置触发模式为off
                ret = camera.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
                if ret != 0:
                    raise HTTPException(status_code=500, detail=f"Failed to set trigger mode for camera {idx+1}")
                    
            except Exception as e:
                print(f"Error setting parameters for high-speed camera {idx+1}: {str(e)}")
                raise
            print(f"Camera {idx+1} parameters set, time elapsed: {time.time() - param_start:.3f}s")

            # 开始取流
            grab_start = time.time()
            ret = camera.MV_CC_StartGrabbing()
            print(f"Camera {idx+1} grabbing started, time elapsed: {time.time() - grab_start:.3f}s")

        print(f"High speed cameras initialization completed, total time: {time.time() - start_time:.3f}s")

    except Exception as e:
        print(f"Error in high speed cameras initialization: {str(e)}")
        raise 